import re

from celery.result import AsyncResult
from django.core.cache import cache
from django.http import HttpResponse, JsonResponse
from rest_framework import mixins
from rest_framework.decorators import action
from rest_framework.exceptions import APIException
from rest_framework.viewsets import ViewSet, GenericViewSet

from celery_task.celery import app
from celery_task.user_task import seckill_task
from luffy_api.libs.send_tx_sms.sms import get_code, send_sms_by_phone
from utils.response import APIResponse
from .models import UserInfo
from .serializer import UserMulLoginSerializer, UserMobileLoginSerializer, UserMobileRegisterSerializer


class UserView(ViewSet):

    def get_serializer(self, data):
        if self.action == 'mul_login':
            return UserMulLoginSerializer(data=data)
        else:
            return UserMobileLoginSerializer(data=data)

    def comm_login(self, request):
        ser = self.get_serializer(data=request.data)
        # 得到对象进行校验
        ser.is_valid(raise_exception=True)  # 会执行序列化字段自己的校验，局部钩子与全局钩子
        # 如果校验通过那么就会继续向下执行，并且在校验的过程中签发了token
        # 如果校验不通过那么就会直接抛出异常，就会被全局异常所捕获到，是drf的异常，然后返回code,与detail(错误的类型)
        # 检验通过签发token得到token
        # 用户名密码校验通过了，在序列化类中--》签发token
        token = ser.context.get('token')
        username = ser.context.get('username')
        icon = ser.context.get('icon')  # icon是个对象  字符串
        # 将token返回给前端
        return APIResponse(token=token, username=username,
                           icon=icon)

    @action(methods=['POST'], detail=False)
    def mul_login(self, request):
        return self.comm_login(request)

    @action(methods=['POST'], detail=False)
    def mobile_login(self, request):
        return self.comm_login(request)

    @action(methods=['GET'], detail=False)
    def mobile(self, request):
        try:
            mobile = request.query_params.get('mobile')
            UserInfo.objects.get(mobile=mobile)  # 有且只有一个才不报错，
            return APIResponse(msg='手机号存在')  # {code:100,msg:手机号存在}
        except Exception as e:
            raise APIException('手机号不存在')  # {code：999,msg:手机号不存在}

    @action(methods=['GET'], detail=False)
    def send_sms(self, request):
        mobile = request.query_params.get('mobile')
        if re.match(r'^1[3-9][0-9]{9}$', mobile):
            code = get_code()
            cache.set('sms_code_%s' % mobile, code)
            res = send_sms_by_phone(mobile, code)
            if res:
                return APIResponse(msg='发送短信成功')
            else:
                return APIResponse(msg='发送短信失败', code=101)
        else:
            return APIResponse(msg='手机号不合法', code=102)


class RegisterView(GenericViewSet, mixins.CreateModelMixin):
    queryset = UserInfo.objects.all()
    serializer_class = UserMobileRegisterSerializer

    def create(self, request, *args, **kwargs):
        response = super().create(request, *args, **kwargs)
        return APIResponse(result=response.data, http_status=response.status_code)


from user.POOL import pool

# def index(request):
#     conn = redis.Redis(connection_pool=pool)
#     conn.incr('page_view')
#     res = conn.get('page_view')
#     return HttpResponse('被你看了%s次' % res)
#
from django_redis import get_redis_connection


def index(request):
    conn = get_redis_connection(alias="default")  # 每次从池中取一个链接
    conn.incr('page_view')  # 页面的访问量
    res = conn.get('page_view')
    return HttpResponse('被你看了%s次' % res)


def seckill(request):
    res = seckill_task.delay()
    return JsonResponse({{'code': 100, 'msg': '正在排队', 'id': str(res)}})


def get_result(request):
    task_id = request.GET.get('id')
    res = AsyncResult(id=task_id, app=app)
    if res.successful():
        result = res.get()  # 7
        return JsonResponse({'code': 100, 'msg': str(result)})
    elif res.failed():
        print('任务失败')
        return JsonResponse({'code': 101, 'msg': '秒杀失败'})
    elif res.status == 'PENDING':
        print('任务等待中被执行')
        return JsonResponse({'code': 102, 'msg': '还在排队'})